/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package web;

import domain.*;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.logging.*;
import javax.servlet.http.HttpServlet;
import javax.xml.parsers.*;
import model.*;
import org.w3c.dom.*;

/**
 *
 * @author user
 */
public class Form {

    public static void main(String[] args) {
        //  Form me1 = new Form("Student", null);
        //   System.out.println("" + me1.toKnowMethod("lastNameRu").getName());
//        me1.
        //  if(1==1) return ;
        Database db = Database.getInstance();
        Student st = db.getStudent(1);
        //    HttpServletRequest myRequest = new MyHttpServletRequest();
        //  myRequest.setAttribute("bean", st);
        Form me = new Form("Student");
        //   me.printList();
        System.out.println(me.form);

    //    me.printSetMethods();

//        for (ColumnProperty col : me.listInputs) {
//            System.out.println(col.getName()+"=");
//        }
    }
    final static int SIZE_FOR_INPUT_TEXT = 40;
    final static int SIZE_FOR_BUTTONS = 150;
    private String name;
    private String tableName;
    private Class typeOfDomainClass;
    private List<ColumnProperty> listInputs = new ArrayList<ColumnProperty>();
    private String form;
    private ResourceBundle rsBundle = ResourceBundle.getBundle("resources/messages", Locale.getDefault());
    // HttpServletRequest request;
    Object bean;
    HttpServlet servlet;
    // Model model = new ModelImpl();

    public Form(String name) {
        try {
            this.name = name;
            // this.request = request;
            //this.servlet = servlet;
            createListInputs();
            createForm();
        } catch (IllegalAccessException ex) {
            Logger.getLogger(Form.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(Form.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(Form.class.getName()).log(Level.SEVERE, null, ex);
        } catch (EltcException ex) {
            Logger.getLogger(Form.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private void createListInputs() {
        try {

            String fullPath = "xml_entity";
//            System.out.println("fullPath = " + fullPath);
            File xmlFile = new File(String.format(fullPath + "/%s.hbm.xml", name));
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(xmlFile);
            doc.getDocumentElement().normalize();
            Node classNode = doc.getElementsByTagName("class").item(0);
            this.tableName = classNode.getNodeName();
            this.typeOfDomainClass = Class.forName(((Element) classNode).getAttribute("name"));
            //  if (request.getAttribute("bean") != null) {
            //     bean = request.getAttribute("bean");
            //  } else {
            bean = typeOfDomainClass.newInstance();
            //  }

            NodeList listOfProperty = classNode.getChildNodes();

            ColumnProperty column = null;
            for (int i = 0; i < listOfProperty.getLength(); i++) {
                if (listOfProperty.item(i).getNodeType() == Node.ELEMENT_NODE) {
                    Element propElement = (Element) listOfProperty.item(i);
                    column = new ColumnProperty();

                    if (propElement.getNodeName().equals("set")) {
                        continue;
                    }
                    if (propElement.getNodeName().equals("many-to-one")) {
                        column.setIsForeignKey(true);
                        Class cl = Class.forName(propElement.getAttribute("class"));
                        column.setForeignClass(cl);
                    } else if (propElement.getNodeName().equals("id")) {
                        column.setIsPrimaryKey(true);
                    }
                    column.setName(propElement.getAttribute("name"));
                    column.setType(propElement.getAttribute("type"));

                    NodeList nodeListOfProperty = listOfProperty.item(i).getChildNodes();
                    for (int j = 0; j < nodeListOfProperty.getLength(); j++) {
                        if (nodeListOfProperty.item(j).getNodeType() == Node.ELEMENT_NODE) {
                            Element columnElement = (Element) nodeListOfProperty.item(j);
                            if (columnElement.getNodeName().equals("column")) {
                                column.setColumnName(columnElement.getAttribute("name"));
//                                column.setIsForeignKey(columnElement.getAttribute("not-null").equals("true") ? true : false);
                                column.setIsNotNull(columnElement.getAttribute("not-null").equals("true") ? true : false);
                                if (columnElement.hasAttribute("length")) {
                                    column.setLength(Integer.parseInt(columnElement.getAttribute("length")));
                                }
                            }
                        }
                    }
                    listInputs.add(column);
                }
            }
        } catch (Exception ex) {
            Logger.getLogger(Form.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private void printList() {
        for (ColumnProperty columnProperty : listInputs) {
            System.out.println("columnProperty = " + columnProperty);
        }
    }

    private void createForm() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, EltcException {

        String required;
        String requiredStyle;
        String maxlength;
        String readonly;
        String patternInputText = "<tr><td>%1$s</td><td><INPUT%2$s%3$s%4$s id='%5$s' type='text' name='%5$s'%6$s size='%7$d' value='%8$s'></td></tr>%n";
        String patternInputSubmitButton = String.format("<tr><td><INPUT type='submit' name='submitButton' style='width:%spx;height:30px' value='Сохранить'></td>", SIZE_FOR_BUTTONS);
        String patternInputResetButton = String.format("<td><INPUT type='reset' style='width:%spx;height:30px'  value='Очистить'></td></tr>", SIZE_FOR_BUTTONS);



        StringBuilder strBuilder = new StringBuilder();
        strBuilder.append(String.format("<FORM name='%s' action='%s'>%n", name, "POST"));
        strBuilder.append("<TABLE>\n");
        for (ColumnProperty columnProperty : listInputs) {

            Method beanMethod = toKnowMethod(columnProperty.getName());
            // System.out.println("beanMethod = " + beanMethod);

            if (columnProperty.isIsForeignKey()) {


                Class cl = columnProperty.getForeignClass();

                if (cl.equals(domain.Sex.class)) {
//                    Sex maleSax = new Sex("male");
//                    maleSax.setId(1);
//                    Sex femaleSax = new Sex("female");
//                    femaleSax.setId(2);
                    // Sex[] array = {maleSax, femaleSax};
                    // List<Sex> array = model.getObjects(Sex.class);
                    List<Sex> arrayList = new ArrayList<Sex>();
                    Sex maleS = new Sex("муж.");
                    maleS.setId(1);
                    Sex femaleS = new Sex("жен.");
                    femaleS.setId(2);
                    arrayList.add(maleS);
                    arrayList.add(femaleS);

                    strBuilder.append(String.format("<tr><td>%1$s</td><td>Муж.<INPUT type='radio' name='sex'>Жен.<INPUT type='radio' name='sex'>%n",
                            "<fmt:message key='sex'/>"));


//
//                    strBuilder.append(String.format("<tr><td>%1$s</td><td><SELECT required='required' name='%2$s' style='width: 1%3$dpx'>%n",
//                            rsBundle.getString(columnProperty.getName()),
//                            columnProperty.getName(),
//                            widhtForInputs));
//                    for (Sex sex : arrayList) {
//                        Sex sexOfBean = (Sex) ((Student) bean).getSex();
//                        System.out.println(sexOfBean + " - " + sex);
//                        String selected = "";
//                        if (sex.equals(sexOfBean)) {
//                            selected = " selected='selected'";
//                        }
//                        System.out.println("selected = " + selected);
//                        // System.out.println("(Student)bean).getSex() = " + ((Student)bean).getSex());
//
//                        strBuilder.append(String.format("<option value='%s'>%s%s</option>%n", sex.getId(), sex.getName(), selected));
//                    }
//                    strBuilder.append("</SELECT></td></tr>\n");
                }

                continue;

            }

            required = columnProperty.isIsNotNull() ? " required='required' class='inpReq'" : "";
            requiredStyle = columnProperty.isIsNotNull() ? " style='background-color: antiquewhite'" : "";
            maxlength = columnProperty.getType().equals("string") ? String.format(" maxlength='%d'", columnProperty.getLength()) : "";
            readonly = columnProperty.isIsPrimaryKey() ? " readonly='readonly'" : "";
            // String valueOfMethod = beanMethod.invoke(bean, null) == null ? "" : beanMethod.invoke(bean, null).toString();
            strBuilder.append(String.format(
                    patternInputText,
                    //rsBundle.getString(columnProperty.getName()),
                    "<fmt:message key='" + columnProperty.getName() + "'/>",
                    requiredStyle,
                    required,
                    maxlength,
                    columnProperty.getName(),
                    readonly,
                    SIZE_FOR_INPUT_TEXT,
                    "${bean." + columnProperty.getName() + "}"));
            //valueOfMethod == null ? "" : valueOfMethod ));
        }
        strBuilder.append(patternInputSubmitButton + "\n");
        strBuilder.append(patternInputResetButton + "\n");
        strBuilder.append("</TABLE>\n");
        strBuilder.append("</FORM>\n");
        form = new String(strBuilder);

    }

    public Method toKnowMethod(String property) {
        Method[] met = domain.Student.class.getMethods();
//        Method[] met = typeOfDomainClass.getMethods();
        for (Method method : met) {
            if (!method.getName().startsWith("get")) {
                continue;
            }
            property = property.substring(0, 1).toUpperCase() + property.substring(1, property.length());
            if (method.getName().contains(property)) {
                return method;
            }
        }
        return null;

    }

    public void printSetMethods() {
        for (ColumnProperty columnProperty : listInputs) {
            System.out.println("bean.set" + makeFirstLetterBig(columnProperty.getName())
                    + "("
                    + String.format("request.getParameter(\"%s\")", columnProperty.getName()) + ");");
        }
    }

    public String getForm() {
        return form;
    }

    private String makeFirstLetterBig(String str) {
        str = str.substring(0, 1).toUpperCase() + str.substring(1, str.length());
        return str;
    }
}
